﻿/*
 * Создан: Оникийчук Антон Игоревич
 * Компания: ООО "ИМСАТ"
 * Дата создания: 21.01.2009
 * Время создания: 10:14
 * Emal разработчика: onikiychuka@gmail.com
 */
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace IMSAT.OFTD.DOM
{
    /// <summary>
    /// Description of NodeCollection.
    /// </summary>
    public class NodeCollection<T> : ObservableCollection<T>
        where T : Node
    {
        private bool _editable;

        /// <summary>
        /// Признак указывающий что коллекцию можно редактировать.
        /// </summary>
        protected bool Editable
        {
            get { return _editable; }
            set { _editable = value; }
        }

        protected override void InsertItem(int index, T item)
        {
            if (_editable)
                base.InsertItem(index, item);
        }

        protected override void ClearItems()
        {
            if (_editable)
                base.ClearItems();
        }

        protected override void MoveItem(int oldIndex, int newIndex)
        {
            if (_editable)
                base.MoveItem(oldIndex, newIndex);
        }

        protected override void RemoveItem(int index)
        {
            if (_editable)
                base.RemoveItem(index);
        }

        protected override void SetItem(int index, T item)
        {
            if (_editable)
                base.SetItem(index, item);
        }

        /// <summary>
        /// Метод для добавления элемента к коллекции
        /// </summary>
        /// <param name="child">элемент</param>
        internal void InsertChild(T child)
        {
            _editable = true;
            Add(child);
            _editable = false;
        }

        internal void Add(IEnumerable<T> nd)
        {
            foreach (T n in nd)
                Add(n);
        }

        /// <summary>
        /// Берёт коллекцию на изменение и возвращает флаг изменения.
        /// </summary>
        /// <returns>Флаг изменения</returns>
        internal NodeCollectionEditingFlag<T> BeginEdit()
        {
            return new NodeCollectionEditingFlag<T>(this);
        }

        #region Nested type: NodeCollectionEditingFlag

        /// <summary>
        /// Класс разрешающий редактировать коллецкию узлов.
        /// </summary>
        internal class NodeCollectionEditingFlag<T1> : IDisposable
            where T1 : Node
        {
            private readonly NodeCollection<T1> _nc;

            public NodeCollectionEditingFlag(NodeCollection<T1> nc)
            {
                _nc = nc;
                _nc._editable = true;
            }

            #region IDisposable Members

            void IDisposable.Dispose()
            {
                _nc._editable = false;
            }

            #endregion

            ~NodeCollectionEditingFlag()
            {
                _nc._editable = false;
            }
        }

        #endregion
    }
}